package cn.wlinker.driver.modbus.tcp.constant;

import com.serotonin.modbus4j.code.DataType;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Optional;

/**
 * 数据类别枚举
 *
 * @author gxsjx
 * @version 1.0
 * @date 2022/10/14
 */
@AllArgsConstructor
@Getter
public enum DataTypeEnum {
    COIL(0, "线圈"),
    SIGNED(DataType.TWO_BYTE_INT_SIGNED, "有符号整型"),
    UNSIGNED(DataType.TWO_BYTE_INT_UNSIGNED, "无符号整型"),
    BINARY(DataType.BINARY, "二进制"),
    LONG_ABCD(DataType.FOUR_BYTE_INT_SIGNED, "长整型ABCD"),
    LONG_CDAB(DataType.FOUR_BYTE_INT_SIGNED_SWAPPED, "长整型CDAB"),
    LONG_DCBA(DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED_SWAPPED, "长整型DCBA"),
    FLOAT_ABCD(DataType.FOUR_BYTE_FLOAT, "单精度浮点型ABCD"),
    FLOAT_CDAB(DataType.FOUR_BYTE_FLOAT_SWAPPED, "单精度浮点型CDAB"),
    DOUBLE_ABCDEFGH(DataType.EIGHT_BYTE_FLOAT, "双精度浮点型ABCDEFGH"),
    DOUBLE_GHEFCDAB(DataType.EIGHT_BYTE_FLOAT_SWAPPED, "双精度浮点型GHEFCDAB"),
    ;

    private Integer type;

    private String typeName;

    /**
     * 获取数据类型对应的寄存器数量
     *
     * @return 寄存器数量
     */
    public int getRegisterCount() {
        if (this.equals(COIL)) {
            return 1;
        }
        return DataType.getRegisterCount(getType());
    }

    /**
     * 获取数据类型对应的字节数
     */
    public int getByteNum() {
        if (this.equals(COIL)) {
            return 1;
        }
        return getRegisterCount() * 2;
    }

    /**
     * 获取对应的java数据类型
     *
     * @return java数据类型
     */
    public Class<?> getJavaType() {
        if (this.equals(COIL)) {
            return Boolean.class;
        }
        return DataType.getJavaType(getType());
    }

    public static Optional<DataTypeEnum> getByType(Integer type) {
        DataTypeEnum[] values = DataTypeEnum.values();
        for (DataTypeEnum dataTypeEnum : values) {
            boolean equals = dataTypeEnum.getType().equals(type);
            if (equals) {
                return Optional.of(dataTypeEnum);
            }
        }
        return Optional.empty();
    }

}
